package com.ruoyi.equip.service.impl;

import com.github.yitter.idgen.YitIdHelper;
import com.ruoyi.common.core.domain.SelectEntity;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.equip.domain.EquipProduct;
import com.ruoyi.equip.domain.entity.table.ProductTableEntity;
import com.ruoyi.equip.mapper.EquipProductMapper;
import com.ruoyi.equip.service.IDeviceInfoService;
import com.ruoyi.equip.service.IEquipProductService;
import com.ruoyi.equip.service.IThingModelService;
import com.ruoyi.equip.util.CacheUtils;
import com.ruoyi.equip.util.ProductCacheUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class EquipProductServiceImpl implements IEquipProductService {
    private static final Logger log = LoggerFactory.getLogger(EquipProductServiceImpl.class);

    private static final Map<Integer, String> NODE_TYPE_MAP = Map.of(
            0, "网关设备",
            1, "网关子设备",
            2, "直连设备"
    );


    private static final Map<Integer, String> TRANS_MODE_MAP = Map.of(
            1, "MQTT",
            2, "UDP",
            3, "TCP"
    );


    private static final Map<Integer, String> LOCATE_MAP = Map.of(
            1, "开启",
            0, "关闭"
    );

    private static final Map<String, String> LOCATE_UPDATE_MAP = Map.of(
            "manual", "手动定位",
            "device", "设备上报"
    );

    @Resource
    private EquipProductMapper equipProductMapper;


    @Resource
    private IDeviceInfoService deviceInfoService;

    @Resource
    private IThingModelService thingModelService;

    @PostConstruct
    public void init(){
        equipProductMapper.selectAll(new EquipProduct()).forEach(ProductCacheUtils::setAliveTime);
    }

    @Override
    public List<EquipProduct> selectAll(EquipProduct equipProduct) {
        return equipProductMapper.selectAll(equipProduct);
    }

    @Override
    @Transactional
    public int addProduct(EquipProduct equipProduct) {
        equipProduct.setId(YitIdHelper.nextId());
        equipProduct.setCreateTime(new Date());
        ProductCacheUtils.setAliveTime(equipProduct);
        return equipProductMapper.insert(equipProduct);
    }

    @Override
    @Transactional
    public int upateProduct(EquipProduct equipProduct) {
        int i = equipProductMapper.updateById(equipProduct);
        ProductCacheUtils.setAliveTime(equipProduct);
        return i;
    }

    @Override
    @Transactional
    public int deleteId(String id) {
        EquipProduct equipProduct = equipProductMapper.selectKeyName(id);
        // 查看是否用户子设备
        boolean hasChild = deviceInfoService.hasDeviceOfProductKey(equipProduct.getProductKey());
        if (hasChild) {
            throw new ServiceException(String.format("%s存在关联设备,不能进行删除", equipProduct.getName()));
        }
        int i = equipProductMapper.deleteById(id);
        ProductCacheUtils.removeAliveTime(equipProduct.getProductKey());
        // 清理物模型数据
        thingModelService.delByProductKey(equipProduct.getProductKey());
        // 清理物模型缓存
        return i;
    }

    @Override
    public List<SelectEntity> selectList() {
        return equipProductMapper.selectList();
    }


    @Override
    public void export(HttpServletResponse response, List<Long> productIds) {
        List<ProductTableEntity> list = equipProductMapper.selectExportData(productIds);
        list.forEach(item -> {
            item.setNodeTypeName(NODE_TYPE_MAP.get(item.getNodeType()));
            item.setTransNodeName(TRANS_MODE_MAP.get(item.getTransMode()));
            item.setOpenLocateName(LOCATE_MAP.get(item.getOpenLocate()));
            if (StringUtils.isNotEmpty(item.getLocateUpdateType()))
                item.setLocateUpdateTypeName(LOCATE_UPDATE_MAP.get(item.getLocateUpdateType()));
        });
        ExcelUtil<ProductTableEntity> util = new ExcelUtil<ProductTableEntity>(ProductTableEntity.class);
        util.exportExcel(response, list, "产品数据");
    }
}
